package com.sqoq.downloader3

import androidx.lifecycle.MutableLiveData
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

class RepuestTool(val lifecycleOwner: CoroutineScope) {

    val baseUiState = MutableLiveData<BaseUiModel>()
     fun <T> request(
        apiCall: suspend CoroutineScope.() -> T,
        onStart: () -> Unit = {},
        onSuccess: (T) -> Unit = {},
        onError: (T) -> Unit = {},
        onComplete: () -> Unit = {},
        onCancel: () -> Unit = {},
        onHttpError: (Throwable?) -> Unit = {},
        onFinally: () -> Unit = {},
        showLoading: Boolean = true,
        showErrorToast: Boolean = true,
        showHttpErrorToast: Boolean = true
    ): Job {
        var job = lifecycleOwner.launch(Dispatchers.Main) {
            try {
                onStart.invoke()
                if (showLoading) {
                    showLoading()
                }
                withContext(Dispatchers.IO) {
                    val result = apiCall.invoke(this)
                    withContext(Dispatchers.Main) {
//                        if (result is ResponseEntity) {
//                            if (result.isSuccess) {
//                                onSuccess(result)
//                            } else {
//                                if (showErrorToast) {
//                                    showToast(result.message)
//                                }
//                                onError(result)
//
//                            }
//                        } else {
                        onSuccess(result)
//                        }
                    }
                }
            } catch (e: Exception) {
                if (e !is CancellationException) {
                    if (showHttpErrorToast) {
                        showToast("网络连接异常")
                    }
                    onHttpError(e)
                }

            }
            if (showLoading) {
                hideLoading()
            }
            onComplete()
        }
        //该方法一定会被执行,协程cancel后也会调用该方法
        job.invokeOnCompletion {
            if (job.isCancelled) {
                onCancel()
            }
            onFinally()
        }
        return job
    }


    //在主线程连续多次调用postValue，则只会分派最后一个值。
    protected fun showToast(text: String?) {
        if (text.isNullOrEmpty()) {
            return
        }
        baseUiState.setValue(BaseUiModel(3, text))
    }

    protected fun showLoading() {
        baseUiState.setValue(BaseUiModel(1))
    }

    protected fun hideLoading() {
        baseUiState.setValue(BaseUiModel(2))
    }


}

data class BaseUiModel(
    val state: Int,
    val toast: String = "",
)

data class ErrorModel(
    val success: Boolean, val code: Int, val msg: String
)